package net.lym.javamind.JavaMap;

import java.util.*;

/**
 * Java Map集合 工具类
 */
public class JavaMapUtil {

    /**
     * 功能: Map集合根据值排序
     */
    public static void mapValueSort() {
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 5);
        map.put("B", 2);
        map.put("C", 8);

        // 创建一个List来保存Map的键值对
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());

        // 对哈希表的值进行排序
        // 对list进行排序，并通过Comparator传入自定义的排序规则
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                return o1.getValue()-o2.getValue();
            }
        });

        // 用迭代器对list中的键值对元素进行遍历
        Iterator<Map.Entry<String,Integer>> iterator=list.iterator();
        while(iterator.hasNext()){
            Map.Entry<String,Integer> ite= iterator.next();
            System.out.println(ite.getKey()+","+ite.getValue());
        }
    }

    /**
     * 功能: Map集合根据值排序
     *
     * 在排序的比较器中，o1.getValue() - o2.getValue() 可能会导致整数溢出。如果 o1.getValue() 和 o2.getValue() 的值较大且符号相反，可能会导致错误的排序结果。
     * 避免整数溢出：使用 Map.Entry.comparingByValue() 替代自定义比较器，避免了整数溢出的风险。
     */
    public static void mapValueSortPlus() {
        Map<String, Integer> map = new HashMap<>();
        map.put("A", 5);
        map.put("B", 2);
        map.put("C", 8);

        // 将map的entrySet放入list集合中，并进行排序
        List<Map.Entry<String,Integer>> list=new ArrayList<>(map.entrySet());
        list.sort(Map.Entry.comparingByValue());

        // 遍历并打印排序后的键值对
        for (Map.Entry<String, Integer> entry : list) {
            System.out.println(entry.getKey() + "," + entry.getValue());
        }
    }

    /**
     * 功能: 根据一个Map的值对另一个Map进行排序
     */
    public static void map1ValueSortByMap2Value() {
        // 初始化第一个Map，包含需要排序的键值对
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("A", 5);
        map1.put("B", 2);
        map1.put("C", 8);

        // 初始化第二个Map，包含排序依据的键值对
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("A", 3);
        map2.put("B", 1);
        map2.put("C", 4);

        // 将第一个Map的键值对转换为List，以便进行排序
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map1.entrySet());

        // 使用Collections.sort方法对List进行排序，排序依据是第二个Map中对应键的值
        Collections.sort(list, new Comparator<Map.Entry<String, Integer>>() {
            @Override
            public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
                // 从第二个Map中获取比较的值
                Integer value1 = map2.get(o1.getKey());
                Integer value2 = map2.get(o2.getKey());
                // 比较并返回结果，用于排序
                return value1.compareTo(value2);
            }
        });

        // 创建一个LinkedHashMap来保存排序后的键值对
        Map<String, Integer> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Integer> entry : list) {
            // 将排序后的键值对放入新的Map中
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        // 打印排序后的Map
        System.out.println("Sorted Map:");
        for (Map.Entry<String, Integer> entry : sortedMap.entrySet()) {
            System.out.println(entry.getKey() + ": " + entry.getValue());
        }
    }

    /**
     * 功能: 根据一个Map的值对另一个Map进行排序
     */
    public static void map1ValueSortByMap2ValuePlus() {
        // 初始化第一个Map，包含需要排序的键值对
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("A", 5);
        map1.put("B", 2);
        map1.put("C", 8);

        // 初始化第二个Map，包含排序依据的键值对
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("A", 3);
        map2.put("B", 1);
        map2.put("C", 4);

        // 检查输入是否为空
        if (map1.isEmpty() || map2.isEmpty()) {
            System.out.println("输入的Map为空，请检查输入数据");
            return;
        }

        // 预先构建排序依据的映射，避免每次比较时都进行查找操作
        Map<String, Integer> sortCriteria = new HashMap<>(map2);

        // 将第一个Map的键值对转换为List，以便进行排序
        List<Map.Entry<String, Integer>> list = new ArrayList<>(map1.entrySet());

        // 使用Lambda表达式简化排序逻辑
        list.sort(Comparator.comparing(entry -> sortCriteria.getOrDefault(entry.getKey(), Integer.MAX_VALUE)));

        // 创建一个LinkedHashMap来保存排序后的键值对
        Map<String, Integer> sortedMap = new LinkedHashMap<>();
        for (Map.Entry<String, Integer> entry : list) {
            sortedMap.put(entry.getKey(), entry.getValue());
        }

        // 打印排序后的Map
        System.out.println("Sorted Map:");
        sortedMap.forEach((key, value) -> System.out.println(key + ": " + value));
    }

}
